package com.cdc.http;
import java.io.IOException;

public class RequestHandler {
    private HttpConnection mHttpConnection;
    private Interceptor mInterceptor;

    public RequestHandler(NetworkExecutor executor) {
        this(new HttpConnection(executor));
    }


    public RequestHandler(HttpConnection httpConnection) {
        this.mHttpConnection = httpConnection;
    }

    public RequestHandler(NetworkExecutor executor, Interceptor interceptor) {
        this.mHttpConnection = new HttpConnection(executor);
        this.mInterceptor = interceptor;
    }

    public <T> Response<T> handle(Request<T> request) {
        long startTime = System.currentTimeMillis();

        if (mInterceptor != null) {
            RequestHandler handler = new RequestHandler(mHttpConnection);
            return mInterceptor.intercept(handler, request);
        } else {
            Protocol protocol = requestNetwork(request);
            T result = null;
            if (protocol.exception == null) {
                try {
                    result = request.parseResponse(protocol.headers, protocol.body);
                } catch (Exception e) {
                    protocol.exception = e;
                }
            }

            return new RestResponse<>(request,protocol.headers, result,
                    System.currentTimeMillis() - startTime, protocol.exception);
        }
    }

    private Protocol requestNetwork(Request<?> request) {
        Protocol protocol = null;
        System.out.println("Only handle network");
        protocol = getHttpProtocol(request);
        return protocol;
    }



    /**
     * Handle retries, and complete the handle network here.
     *
     * @param request handle object.
     * @return {@link Protocol}.
     */
    private Protocol getHttpProtocol(BasicRequest<?> request) {
        Protocol result = new Protocol();
        Connection connection = mHttpConnection.getConnection(request);
        result.headers = connection.responseHeaders();
        result.exception = connection.exception();
        if (result.exception == null && connection.serverStream() != null) {
            try {
                result.body = IOUtils.toByteArray(connection.serverStream());
            } catch (IOException e) {
                result.exception = e;
            }
        }
        IOUtils.closeQuietly(connection);
        return result;
    }

    /**
     * Process the response cache.
     */


    private static class Protocol {
        /**
         * Server response header.
         */
        private Headers headers;

        /**
         * Data.
         */
        private byte[] body;
        /**
         * Exception of connection.
         */
        private Exception exception;
    }
}

